package model

import (
	"gowork/cinemaTicket/utils"
	"sync"
	"time"
)

type OnlineMovie struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	Duration int
	Price float64
	DiscussList []*Discuss `xorm:"-"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Discuss struct {
	Id int64 `xorm:"pk autoincr"`
	OnlineMovieId int64
	OnlineMovieName string
	UserId int64
	UserName string
	Content string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Cinema struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	Address string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Film struct {
	Id int64 `xorm:"pk autoincr"`
	CinemaId int64
	CinemaName string
	MovieId int64
	MovieName string
	MovieDuration int
	ShowDate string
	ShowTime string
	ProjectionRoomId int64
	ProjectionRoomName string
	NumberOfVotes int
	TicketPrice float64
	CreatedAt time.Time
	UpdatedAt time.Time
}

type ProjectionRoom struct {
	Id int64 `xorm:"pk autoincr"`
	Name string
	NumberOfSeats int
	CreatedAt time.Time
	UpdatedAt time.Time
}

type ViewingSeat struct {
	Id int64 `xorm:"pk autoincr"`
	SeatNumber int
	FilmId int64
	ProjectionRoomId int64
	Occupied int  // 1 占用  2 为占用
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Ticket struct {
	Id int64 `xorm:"pk autoincr"`
	FilmId int64
	MovieId int64
	MovieName string
	MovieDuration int
	ShowDate string
	ShowTime string
	ProjectionRoomId int64
	ProjectionRoomName string
	TicketPrice float64
	SeatNumber int
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (onlineMovie *OnlineMovie)GenerateMovieTickets(sdList []string, stList []string, omList []*OnlineMovie, prList []*ProjectionRoom, c *Cinema)(map[string]interface{}, error){

	w := new(utils.Worker)

	for _, sdv := range sdList{
		for _, stv := range stList{
			for _, prv := range prList{
				for _, omv := range omList{
					var f = Film{
						Id:       w.GetId(),
						CinemaId: c.Id,
						CinemaName: c.Name,
						MovieId : omv.Id,
						MovieName : omv.Name,
						MovieDuration : omv.Duration,
						ShowDate : sdv,
						ShowTime :	stv,
						ProjectionRoomId : prv.Id,
						ProjectionRoomName : prv.Name,
						NumberOfVotes : prv.NumberOfSeats,
						TicketPrice : omv.Price,
						CreatedAt : time.Now(),
						UpdatedAt : time.Now(),
					}
					x.Insert(&f)

					for i := 1; i <= prv.NumberOfSeats; i++{
						var vs ViewingSeat
						vs.Id = w.GetId()
						vs.SeatNumber = i
						vs.FilmId = f.Id
						vs.ProjectionRoomId = f.ProjectionRoomId
						vs.Occupied = 1
						vs.CreatedAt = time.Now()
						vs.UpdatedAt = time.Now()
						x.Insert(&vs)
					}
				}
			}
		}
	}

	return map[string]interface{}{"message":"成功", "code":200}, nil
}

func (onlineMovie *OnlineMovie)QueryFilmSeat(fId int64, prId int64)([]*ViewingSeat, error){

	var vsList []*ViewingSeat
	x.Where("film_id = ?", fId).And("projection_room_id = ?", prId).Find(&vsList)

	return vsList, nil
}

var lock sync.Mutex

func (onlineMovie *OnlineMovie)BuyFilm(f *Film, vs *ViewingSeat)(map[string]interface{}, error){

	lock.Lock()

	lvs := new(ViewingSeat)
	x.Id(vs.Id).Get(lvs)
	if lvs.Occupied == 2{

		lock.Unlock()

		return map[string]interface{}{"message":"该座次已被预约", "code":200}, nil
	}

	w := new(utils.Worker)

	var t  = Ticket{
		Id:                 w.GetId(),
		FilmId:             f.Id,
		MovieId:            f.MovieId,
		MovieName:          f.MovieName,
		MovieDuration:      f.MovieDuration,
		ShowDate:           f.ShowDate,
		ShowTime:           f.ShowTime,
		ProjectionRoomId:   f.ProjectionRoomId,
		ProjectionRoomName: f.ProjectionRoomName,
		TicketPrice:        f.TicketPrice,
		SeatNumber:         vs.SeatNumber,
		CreatedAt:          time.Now(),
		UpdatedAt:          time.Now(),
	}
	x.Insert(&t)

	vs.Occupied = 2
	x.Id(vs.Id).Update(vs)

	var fv Film
	x.Id(f.Id).Get(&fv)
	fv.NumberOfVotes -= 1
	x.Id(f.Id).Update(&fv)

	lock.Unlock()

	return map[string]interface{}{"message":"成功", "code":200}, nil
}

func (onlineMovie *OnlineMovie)QueryOnlineMovie(d string)([]*Film, error){

	var fList []*Film
	x.Where("show_date = ?", d).Find(&fList)

	return fList, nil
}